package com.xunk.equipment.service.dnake.service.impl;

import com.xunk.common.core.constant.CacheConstants;
import com.xunk.common.core.enums.dnake.DnakeActionEnum;
import com.xunk.common.core.enums.dnake.DnakeDeviceTypeEnum;
import com.xunk.common.core.utils.DataUtils;
import com.xunk.common.core.utils.IdUtils;
import com.xunk.common.redis.service.RedisService;
import com.xunk.common.security.utils.SecurityUtils;
import com.xunk.equipment.domain.EquipmentDO;
import com.xunk.equipment.service.BaseService;
import com.xunk.equipment.service.dnake.DnakePublishComponent;
import com.xunk.equipment.service.dnake.service.DnakeKeyControlPanelService;
import com.xunk.equipment.service.dnake.vo.DnakeMqttRequestDataMessage;
import com.xunk.equipment.vo.response.DnakeLightResponse;
import com.xunk.equipment.vo.response.DnakeResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import com.xunk.common.core.domain.EquipmentResponse;

@Service("dnake-four-key-switch")
@Slf4j
public class DnakeFourLightServiceImpl implements DnakeKeyControlPanelService {

    @Autowired
    DnakePublishComponent dnakePublishComponent;
    @Autowired
    protected RedisService redisService;
    @Autowired
    @Lazy
    BaseService baseService;

    @Override
    public EquipmentResponse getEquipmentInfo(EquipmentDO equipmentDO) {
        String ancestor = baseService.findAncestorByDeptId(equipmentDO.getDeptId());
        String key = ancestor.concat(":").concat(equipmentDO.getDeviceSn());
        Map<String, Object> cacheMap = redisService.getCacheMap(key);
        /*if (DataUtils.isEmpty(cacheMap)) {
            // 补偿机制
            String deviceSn = equipmentDO.getDeviceSn();
            String messageId = IdUtils.simpleUUID();
            MqttMessage message = new MqttMessage();
            DnakeMqttRequestDataMessage vo = new DnakeMqttRequestDataMessage();
            String[] device = deviceSn.split("-");
            vo.setUuid(messageId)
                    .setAction(DnakeActionEnum.READDEV.getCode())
                    .setDevType(equipmentDO.getDeviceType())
                    .setDevNo(Integer.valueOf(device[1]))
                    .setDevCh(1);
            // 设备绑定的网关deviceName
            String toDev = deviceSn.substring(0, deviceSn.indexOf("-"));

            DnakeRequestMqttMessage mqttMessage = new DnakeRequestMqttMessage();
            mqttMessage.setData(vo)
                    .setFromDev("readDev")
                    .setToDev(toDev);

            message.setPayload(JSONObject.toJSONString(mqttMessage).getBytes(StandardCharsets.UTF_8));
            String topic = "/" + productKey + "/" + toDev + "/get";
            client.publish(topic, message);
        }
*/
//        XunkAssert.notEmpty(cacheMap, String.format("设备%s属性不存在，请稍后在查！", equipmentDO.getDeviceSn()));
        DnakeResponse deviceResponse = new DnakeResponse();
        if (DataUtils.isNotEmpty(cacheMap)) {
            deviceResponse.setDeviceSn(equipmentDO.getDeviceSn());
            List<DnakeLightResponse> responseList = new LinkedList<>();


            int channels = Integer.parseInt(cacheMap.get("channels").toString());
            for(int i = 1; i <= channels; i++){
                DnakeLightResponse response = new DnakeLightResponse();
                response.setDevCh(i);

                String hey = i+".state";
                response.setOn(Integer.valueOf(String.valueOf(cacheMap.get(hey))));
                responseList.add(response);
            }

            deviceResponse.setSupplier(equipmentDO.getSupplier());
            deviceResponse.setCandidateModel(baseService.getCandidateModel(equipmentDO.getDeviceBaseId()));
            deviceResponse.setData(responseList);
        }
        return deviceResponse;
    }

    @Override
    public Boolean control(EquipmentDO equipmentDO, String type, String value) {
        try {
            String deviceSn = equipmentDO.getDeviceSn();
            String messageId = IdUtils.simpleUUID();
            // 放到redis种，返回后知道是哪个用户(userId)发送的具体消息；
            Map<String, Object> map = new HashMap<>();
            // 获取userId
            Long userId = SecurityUtils.getUserId(false);
            map.put("userId", userId);
            map.put("deviceType", equipmentDO.getDeviceType());
            map.put("type", type);
            map.put("value", value);
            map.put("deviceSn", deviceSn);
            redisService.setCacheObject(CacheConstants.DNAKE_CONTROL_INFO + messageId, map, 1, TimeUnit.MINUTES);

            DnakeMqttRequestDataMessage vo = new DnakeMqttRequestDataMessage();
            String[] device = deviceSn.split("-");
            DnakeDeviceTypeEnum typeEnum = DnakeDeviceTypeEnum.getDeviceTypeEnumByType(equipmentDO.getDeviceType());
            Integer devType = Integer.valueOf(typeEnum.getCode().split("-")[0]);
            vo.setCmd(value)
                    .setUuid(messageId)
                    .setAction(DnakeActionEnum.CTRLDEV.getCode())
                    .setDevType(devType)
                    .setDevNo(Integer.valueOf(device[1]))
                    .setDevCh(Integer.valueOf(type));
            // 设备绑定的网关deviceName
            String toDev = deviceSn.substring(0, deviceSn.indexOf("-"));

            dnakePublishComponent.publish(vo, toDev, equipmentDO.getDeviceSn());;
            return true;
        } catch (Exception e) {
            log.error("设备发送MQTT消息错误：", e);
            return false;
        }
    }

}
